<?php
/**
 * Created by PhpStorm.
 * User: ytlmi
 * Date: 2017/10/17
 * Time: 16:52
 */

namespace org\util\wordtool;

class Style
{
    protected $dom=null;

    public function __construct()
    {
        $this->dom=new \DOMDocument();
    }

    /**
     * @param array $style
     * @return \DOMElement
     * @throws \Exception
     * 段落样式，可选：
     * space:行距
     * spaceBefore:段前间距
     * spaceAfter:段后间距
     * chars:首行缩进
     * align:水平对齐
     */
    public function createPPR($style)
    {
        $style ? $style = $style + StaticElement::DEFAULT_STYLE_PR : $style=StaticElement::DEFAULT_STYLE_PR;
        $arr_style=[];
        $pPr=$this->dom->createElement('w:pPr');
        if (isset($style['space']) || isset($style['spaceBefore']) || isset($style['spaceAfter'])){
            if(!isset($style['space'])) $style['space']=null;
            if(!isset($style['spaceBefore'])) $style['spaceBefore']=null;
            if(!isset($style['spaceAfter'])) $style['spaceAfter']=null;
            try{
                $arr_style['spacing']=$this->setSpacing($style['space'],$style['spaceBefore'],$style['spaceAfter']);
            }catch (\Exception $e){
                throw new \Exception($e->getMessage());
            }

        }
        try{
            if (isset($style['chars'])) $arr_style['chars']=$this->setChars($style['chars']);
            if (isset($style['align'])) $arr_style['align']=$this->setAlign($style['align']);
        }catch (\Exception $e){
            throw new \Exception($e->getMessage());
        }

        foreach ($arr_style as $item){
            $pPr->appendChild($item);
        }
        return $pPr;
    }

    /**
     * @param array $style
     * @return \DOMElement
     * @throws \Exception
     * 单元格样式，可选：
     * width：宽度
     * color：单元格底色
     * align：水平对齐方式
     * vAlign:垂直对齐
     * border：数组，边框样式
     * */
    public function createTCPR($style)
    {
        $style ? $style = $style + StaticElement::DEFAULT_STYLE_CELL : $style=StaticElement::DEFAULT_STYLE_CELL;
        $arr_style=[];
        $tcPr=$this->dom->createElement('w:tcPr');
        try{
            if (isset($style['width'])) $arr_style['width']=$this->setWidth($style['width']);
            if (isset($style['color'])) $arr_style['color']=$this->setTcColor($style['color']);
            if (isset($style['align'])) $arr_style['align']=$this->setAlign($style['align']);
            if (isset($style['vAlign'])) $arr_style['vAlign']=$this->setVAlign($style['vAlign']);
        }catch (\Exception $e){
            throw new \Exception($e->getMessage());
        }
        if (isset($style['border'])){
            if (is_array($style['border'])){
                $arr_border=$style['border'];
            }else{
                $arr_border=array('top'=>$style['border'],'bottom'=>$style['border'],'left'=>$style['border'],'right'=>$style['border']);
            }
            try{
                $arr_style['border']=$this->setBorder('w:tcBorders',$arr_border);
            }catch (\Exception $e){
                throw new \Exception($e->getMessage());
            }
        }
//        var_dump($arr_style);
        foreach ($arr_style as $item){
            $tcPr->appendChild($item);
        }
        return $tcPr;
    }

    /**
     * @param array $style
     * @return \DOMElement
     * @throws \Exception
     * 表格样式，可选：
     * width：宽度
     * align：水平对齐方式
     * border：数组，边框样式
     * */
    public function createTBLPR($style)
    {
        $style ? $style = $style + StaticElement::DEFAULT_STYLE_TB : $style=StaticElement::DEFAULT_STYLE_TB;
        $arr_style=[];
        $tblPr=$this->dom->createElement('w:tblPr');
        try{
            if (isset($style['width'])) $arr_style['width']=$this->setWidth($style['width']);
            if (isset($style['align'])) $arr_style['align']=$this->setAlign($style['align']);
        }catch (\Exception $e){
            throw new \Exception($e->getMessage());
        }

        if (isset($style['border'])){
            if (is_array($style['border'])){
                $arr_border=$style['border'];
            }else{
                $arr_border=array('top'=>$style['border'],'bottom'=>$style['border'],'left'=>$style['border'],'right'=>$style['border']);
            }
            try{
                $arr_style['border']=$this->setBorder('w:tblBorders',$arr_border);
            }catch (\Exception $e){
                throw new \Exception($e->getMessage());
            }
        }
//        if (isset($style['margin'])){
//            if (is_array($style['margin'])){
//                $arr_margin=$style['margin'];
//            }else{
//                $arr_margin=array('top'=>$style['margin'],'bottom'=>$style['margin'],'left'=>$style['margin'],'right'=>$style['margin']);
//            }
//            try{
//                $arr_style['margin']=$this->setCellMargin($arr_margin);
//            }catch (\Exception $e){
//                throw new \Exception($e->getMessage());
//            }
//
//        }
        foreach ($arr_style as $item){
            $tblPr->appendChild($item);
        }
        return $tblPr;
    }

    /**
     * @param int $chars
     * @return \DOMElement
     * @throws \Exception
     * 设置首行缩进
     */
    protected function setChars($chars)
    {
        if (!is_int($chars+0))  throw new \Exception('错误的缩进值：'.$chars);
        $ind=$this->dom->createElement('w:ind');
        $ind->setAttribute('w:firstLineChars',$chars);
        $ind->setAttribute('w:firstLine',0);
        return $ind;
    }

    /**
     * @param string $align
     * @return \DOMElement
     * @throws \Exception
     * 设置水平对齐方式
     */
    protected function setAlign($align)
    {
        if (!in_array($align,array('left','right','center')))  throw new \Exception('错误的对齐方式：'.$align);
        $jc=$this->dom->createElement('w:jc');
        $jc->setAttribute('w:val',$align);
        return $jc;
    }

    /**
     * @param string $vAlign
     * @return \DOMElement
     * @throws \Exception
     * 设置垂直对齐方式
     */
    protected function setVAlign($vAlign)
    {
        if (!in_array($vAlign,array('top','bottom','center')))  throw new \Exception('错误的对齐方式：'.$vAlign);
        $jc=$this->dom->createElement('w:vAlign');
        $jc->setAttribute('w:val',$vAlign);
        return $jc;
    }

    /**
     * @param int $space
     * @param int $spaceBefore
     * @param int $spaceAfter
     * @return \DOMElement
     * @throws \Exception
     * 设置行距、段前段后间距
     */
    protected function setSpacing($space=null,$spaceBefore=null,$spaceAfter=null)
    {
        $spacing=$this->dom->createElement('w:spacing');
        $spacing->setAttribute('w:lineRule','atLeast');
        if ($space){
            if (!is_int($space+0))  throw new \Exception('错误的行间距：'.$space);
            $spacing->setAttribute('w:line',$space);
        }
        if ($spaceBefore){
            if (!is_int($spaceBefore+0))  throw new \Exception('错误的段前间距：'.$spaceBefore);
            $spacing->setAttribute('w:beforeLines',$spaceBefore);
        }
        if ($spaceAfter){
            if (!is_int($spaceAfter+0))  throw new \Exception('错误的段后间距：'.$spaceAfter);
            $spacing->setAttribute('w:afterLines',$spaceAfter);
        }
        return $spacing;
    }

    /**
     * @param int $width
     * @return \DOMElement
     * @throws \Exception
     * 设置单元格宽度
     */
    protected function setWidth($width)
    {
        if (!is_int($width+0))  throw new \Exception('错误的宽度值：'.$width);
        $tcW=$this->dom->createElement('w:tcW');
        $tcW->setAttribute('w:w',$width);
        //TODO:type值的选择
        $tcW->setAttribute('w:type','dxa');
//        var_dump($tcW);
        return $tcW;

    }

    /**
     * @param int $color
     * @return \DOMElement
     * @throws \Exception
     * 设置单元格颜色
     * 16进制
     * example:'#123ABC'
     */
    protected function setTcColor($color)
    {
        try{
            $color=self::checkColor($color);
        }catch (\Exception $e){
            throw new \Exception($e->getMessage());
        }
        //生成颜色元素
        $shd=$this->dom->createElement('w:shd');
        $shd->setAttribute('w:val','clear');
        $shd->setAttribute('w:color',$color);
        $shd->setAttribute('w:fill','auto');
        return $shd;
    }

    /**
     * @param int $color
     * @return \DOMElement
     * @throws \Exception
     * 设置颜色
     */
    public static function checkColor($color)
    {
        //判断是否是预设颜色
        if (isset(StaticElement::PRE_COLOR[$color])) $color=StaticElement::PRE_COLOR[$color];
        //去掉“#”
        $color=str_replace('#','',$color);
        //验证颜色格式
        if (strlen($color)!=6){
            throw new \Exception('颜色格式错误：'.$color);
        }else{
            $arr_color=[
                substr($color,0,2),
                substr($color,2,2),
                substr($color,4,2),
            ];
            foreach ($arr_color as $item) {
                if ($item!='00'){//hexdec会将不能转换的返回0 故先排除0
                    $dec=hexdec($item);
                    if (!($dec>0 && $dec<256)) throw new \Exception('颜色格式错误：'.$color);
                }
            }
        }
        return$color;
    }

    /**
     * @param string $elementName
     * @param array $arr_border
     * @return \DOMElement
     * @throws \Exception
     * 设置边框，参数为数组，
     * key值为位置，每个元素为字符串，
     * 格式为"type=single,color=000000,size=12"
     * 举个栗子：['top'=>'type=nil']
     */
    protected function setBorder($elementName, array $arr_border)
    {
        $arr_pos=['top','bottom','left','right'];
        $arr_value=['type'=>'w:val','color'=>'w:color','size'=>'w:sz'];
        $doc_bd=$this->dom->createElement($elementName);
        foreach ($arr_border as $pos=>$border) {
            if (!in_array($pos,$arr_pos))  throw new \Exception('错误的参数：'.$pos.'=>'.$border);
            $doc_bd_item=$this->dom->createElement('w:'.$pos);
            $arr_items=preg_split('/,/',$border);
            foreach ($arr_items as $str_item){
                $arr=preg_split('/=/',$str_item);
                $key=$arr[0];
                $item=$arr[1];
                if (!$arr_value[$key])  throw new \Exception('参数错误：'.$key);
                $doc_bd_item->setAttribute($arr_value[$key],$item);
            }
            $doc_bd_item->setAttribute('w:space','0');
            $doc_bd->appendChild($doc_bd_item);
        }
        return $doc_bd;
    }

    /**
     * @param array $arr_margin
     * @return \DOMElement
     * @throws \Exception
     * 设置单元格边距，参数为数组，
     * key值为位置，每个元素为int数值，
     * 举个栗子：array('top'=>0,'bottom'=>0)
     */
    protected function setCellMargin(array $arr_margin)
    {
        $arr_pos=array('top','bottom','left','right');
        $doc_mar=$this->dom->createElement('w:tblCellMar');
        foreach ($arr_margin as $pos=>$margin) {
            if (!in_array($pos,$arr_pos))  throw new \Exception('错误的参数：'.$pos.'=>'.$margin);
            $doc_mar_item=$this->dom->createElement('w:'.$pos);
            $doc_mar->appendChild($doc_mar_item);
        }
        return $doc_mar;
    }

}